/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */
#include "CameraController.h"
#include "InputSystem.h"

namespace Fish3D
{
	CameraController::CameraController(Ogre::Camera* camera)
	: _camera(camera)
	{
		Ogre::SceneManager* sceneMgr=_camera->getSceneManager();
		_raySceneQuery=sceneMgr->createRayQuery(Ogre::Ray());

		//init camera
		_camera->setNearClipDistance(1.0f);

		_camera->setFarClipDistance(99999*6);
		_camera->setPosition(1500,65,1500);
		_camera->setOrientation(Ogre::Quaternion(0.998, -0.0121, -0.0608, -0.00074));

	}

	CameraController::~CameraController()
	{
		if(_raySceneQuery){
			delete _raySceneQuery;
		}
	}


	void CameraController::update(float deltaT)
	{
		// Move about 100 units per second
		_moveScale = MoveSpeed * deltaT;
		// Take about 10 seconds for full rotation
		_rotScale = RotateSpeed * deltaT;

		_rotX = 0;
		_rotX = 0;
		_translate = Ogre::Vector3::ZERO;

		processMouse();
		processKeyboard();
		
		moveCamera();
		keepAboveTerrain();
		

	}

	void CameraController::keepAboveTerrain()
	{
		Ogre::SceneManager* sceneMgr=_camera->getSceneManager();
		// Check camera height
		Ogre::Vector3 pos=_camera->getPosition();
		
		_raySceneQuery->setRay(Ogre::Ray(pos + Ogre::Vector3(0,1000000,0), Ogre::Vector3::NEGATIVE_UNIT_Y));
		Ogre::RaySceneQueryResult& qryResult = _raySceneQuery->execute();
        Ogre::RaySceneQueryResult::iterator i = qryResult.begin();

        if (i != qryResult.end() && i->worldFragment){
			if (pos.y < i->worldFragment->singleIntersection.y + 60){
                _camera->setPosition(pos.x, i->worldFragment->singleIntersection.y + 60,pos.z);
			}
        }
	}


	void CameraController::processKeyboard()
	{
		OIS::Keyboard* keyboard=InputSystem::getSingleton().getKeyboard();

		// Move camera left
		if(keyboard->isKeyDown(OIS::KC_A)){
			_translate.x = -_moveScale;
		}

		// Move camera right
		if(keyboard->isKeyDown(OIS::KC_D)){
			_translate.x = _moveScale;	
		}

		// Move camera forward
		if(keyboard->isKeyDown(OIS::KC_W)){
			_translate.z = -_moveScale;	
		}

		// Move camera backward
		if(keyboard->isKeyDown(OIS::KC_S)){
			_translate.z = _moveScale;
		}
	}

	void CameraController::processMouse()
	{
		OIS::Mouse* mouse=InputSystem::getSingleton().getMouse();
		
		const OIS::MouseState &state = mouse->getMouseState();

		
		if(state.buttonDown(OIS::MB_Right)){

			_rotX = Ogre::Degree(-state.X.rel * 0.13);
			_rotY = Ogre::Degree(-state.Y.rel * 0.13);
			//_translate.x += state.X.rel * 0.13;
			//_translate.y -= state.Y.rel * 0.13;
		}else if(state.buttonDown(OIS::MB_Left)){
			_translate.x += state.X.rel * 0.13;
			_translate.y -= state.Y.rel * 0.13;
			//_rotX = Ogre::Degree(-state.X.rel * 0.13);
			//_rotY = Ogre::Degree(-state.Y.rel * 0.13);
		}
	}

	void CameraController::moveCamera()
	{
		_camera->yaw(_rotX);
		_camera->pitch(_rotY);
		_camera->moveRelative(_translate);

	}

}
